window.initPointer = ()=>{
  // var startRotation = 10.351479567667253; // 地图倾斜角度
  // var startPitch = 37.800490797546026;
  // var startZoom = 6.14; // 地图缩放
  // var startCenter = [106.75452808454634, 28.695795205023604]; // 起始位置

  var startRotation = 10.351479567667253; // 地图倾斜角度
  // var startRotation = 0; // 地图倾斜角度
  var startPitch = 37.800490797546026;
  var startZoom = 8.33; // 地图缩放
  var startCenter = [111.4768137426675, 27.91156167811653]; // 起始位置

  var map = new AMap.Map('container', {
    mapStyle: 'amap://styles/97be51efb13a493d98b4235dcf4ca710',
    // mapStyle: 'amap://styles/eac49194084ba6dbc7df64b6d3b48599',
    zoom: startZoom,
    center: startCenter,
    // features: ['bg', 'road', 'building', "point"],
    pitch: startPitch,
    rotation: startRotation,
    skyColor: '#39346a',
      rotateEnable: false,
    viewMode: '3D' // 地图模式
  });
  // new AMap.TileLayer.RoadNet({
  //     zIndex:10,
  //     zooms:[5.17, 9.27],
  //     opacity: .5,
  //     map,
  // });
  window.map = map;
  const container = map.getContainer();

  /*
  * 添加Canvas图层
  */
  var canvas = document.createElement('canvas');
  // 设置 canvas
  canvas.width =  container.offsetWidth ;
  canvas.height = container.offsetHeight ;
  const context = canvas.getContext('2d')
    // canvas 离线绘制
  const canvasBuffer = document.createElement('canvas');
    canvasBuffer.width =  container.offsetWidth ;
    canvasBuffer.height = container.offsetHeight ;
  // 设置 canvas
  const contextBuffer = canvasBuffer.getContext('2d');

  let changing = false;
  let timer;
  let changingListioner = ()=>{
    changing = true;
    clearTimeout(timer);
    timer = setTimeout(()=>{
      changing = false;
    }, 100)
  };
  map.on("mapmove", changingListioner);
  map.on("zoomchange", changingListioner);
  map.on("resize", changingListioner);
  // 创建一个自定义图层

  map.on("complete", ()=>{
    var customLayer = new AMap.CustomLayer(canvasBuffer, {
      zIndex: 12,
      zooms: [1, 18] // 设置可见级别，[最小级别，最大级别]
    });
    map.add(customLayer);
  })

  window.canvas = canvas;

  // 构建点栈
  window.points = {};
  // 构建覆盖物栈
  // window.marks = {};
  window.map = map

  // 绘制方法
  let zoom = map.getZoom(); // 缓存当前 zoom
    // let testTime = Date.now();
  function drawBuffer() {
    contextBuffer.clearRect(0, 0, canvas.width, canvas.height)
    const now = Date.now();
    const entries = Object.getOwnPropertySymbols(points);
    if(changing){
      zoom = map.getZoom();
    }
    for (var i = 0; i < entries.length; i++) {
      const key = entries[i];
      const point = points[key];

      if (point.alive) {
        point.draw(now, zoom)
      } else {
        // 删除亮点
        delete points[key];
        // 删除覆盖物
        // map.remove(marks[key])
        // delete marks[key];
      }
    }
      // const fps = Math.floor(1000/(Date.now() - testTime));
      // testTime = Date.now();
      // contextBuffer.fillText('buffer fps '+fps,canvas.width - 100,canvas.height- 20);
      AMap.Util.requestAnimFrame(drawBuffer);
  }
    //
    // let testTimeDraw = Date.now();
    // function draw(){
    //   context.clearRect(0, 0, canvas.width, canvas.height);
    //   context.drawImage(canvasBuffer, 0, 0);
    //   const fps = Math.floor(1000/(Date.now() - testTimeDraw));
    //   context.fillText('image fps '+fps,canvas.width - 100,canvas.height- 50);
    //   testTimeDraw = Date.now();
    //   AMap.Util.requestAnimFrame(draw);
    // }

  // // 经纬度转相对位置
  // function getLayerBounds(){
  //   const bounds = CanvasLayer.getBounds();
  //   // const center = bounds.getCenter();
  //   const nw = bounds.getNorthWest();
  //   const ne = bounds.getNorthEast();
  //   const se = bounds.getSouthEast();
  //   const sw = bounds.getSouthWest();
  //   return [
  //     [nw.P || nw.lng, nw.O || nw.lat],
  //     [ne.P || ne.lng, ne.O || ne.lat],
  //     [se.P || se.lng, se.O || se.lat],
  //     [sw.P || sw.lng, sw.O || sw.lat],
  //   ]
  // }

  /**
   * 经纬度 转 坐标
   * @param {*} x
   * @param {*} y
   */
  function lnglat2container(x, y) {
    var lnglat = new AMap.LngLat(x, y);
    var pixel = map.lnglatTocontainer(lnglat);
    return pixel.floor();
  }

  /**
   * 创建一个标记
   * @param {*} ctx
   * @param {*} lng
   * @param {*} lat
   * @param {*} rmax 最大半径
   * @param {*} color 颜色
   * @param {*} duration 延时
   * @param {*} loopQueue 标记队列
   */
  function Point(ctx, lng, lat, rmax, color, duration, loopQueue) {
    this.id = Symbol('pointid');
    this.startTime = Date.now();
    this.alive = true;
    // this.timer = 0;
    ctx.fillStyle = color;
    ctx.shadowColor = "rgba(255,215, 0, 1)";
    // contextBuffer.shadowBlur = 10;
    // ctx.shadowBlur = 10;
    // ctx.strokeStyle = color;
    // ctx.lineWidth = 1;
    this.offset = lnglat2container(lng, lat);
    this.draw = (now, zoom) => {
      this.timer++;
      if(changing){
        this.offset = lnglat2container(lng, lat);
      }
      if(this.offset.x < 0) return;
      if(this.offset.y < 0) return;
      if(this.offset.x > canvas.width) return;
      if(this.offset.y > canvas.height) return;
      const lifecycle = now - this.startTime
      // 放大系数
      const zoomRate = Math.pow((Math.max(2, zoom - 5)), 2) / 20;
      // 动画进度
      let per = Math.max(0, Math.min(lifecycle / duration, 1))

      let perOpacity = 0
      let delay = 60 * 1000; // 停留 60 秒
      let isInLifeCycle = lifecycle < (delay + duration * 2)
      // 半径心跳
      if(per >=1 && lifecycle < delay){
        const wave = lifecycle / 800;
        per = 1 + Math.abs(0.2 * (Math.sin(wave * Math.PI) + 1));
      }

      if(lifecycle >= delay){
        // 透明度渐出
        perOpacity = Math.max(0, Math.min(((now - delay) - this.startTime) / duration, 1))
      }else{
        // 透明度心跳
        const wave = lifecycle / 800;
        perOpacity = Math.abs(0.25 * (Math.cos(wave * Math.PI) + 2));
      }
      ctx.beginPath();
      this.nowR = Math.min(rmax * per * zoomRate, 5);
      ctx.shadowBlur = !changing ? Math.max(5, this.nowR * 2) : 0
      ctx.globalAlpha = Math.min(0.8, (1 - perOpacity));
      ctx.arc(this.offset.x, this.offset.y, this.nowR, 0, 7); // 2 * PI
      ctx.fill();
      // ctx.arc(this.offset.x, this.offset.y, this.nowR, 0, 2 * Math.PI);
      // ctx.arc(this.offset.x, this.offset.y, this.nowR, 0, 7); // 2 * PI
      // ctx.stroke();
      // 重置
      if (per >= 1 && perOpacity>=1 && !isInLifeCycle) {
        this.alive = false;
        this.startTime = Date.now()
      }
    };
    loopQueue[this.id] = this;
  }


  // const pow = Math.pow,
  //   c1 = 1.70158,
  //   c3 = c1 + 1
  // function easeInExpo (x) {
  //   return x === 0 ? 0 : Math.pow( 2, 10 * x - 10 );
  // }

  // function easeOutBack (x) {
  //   return 1 + c3 * Math.pow( x - 1, 3 ) + c1 * Math.pow( x - 1, 2 );
  // }

  // setInterval(drawBuffer, 20);
  drawBuffer();
  // draw();
  return function point(lng, lat, r = 7, color='gold', duration = 300) {
    if(lng && lat) {
      // 构造亮点
      const point = new Point(contextBuffer, lng, lat, r, color, duration, points);

      // 构造坐标点
      // const mark = new AMap.Marker({
      //   icon: "https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png",
      //   position: [lng, lat]
      // })
      // // map.add(mark);
      // window.marks[point.id] = mark;
    }
  }
}
